import { get_gun, clear_gun, send_step, set_st } from 'base/api';
import { g_db, s_psn, g_wsn, g_psn } from 'db/state';
import { uDb, urlTb, cline } from 'sui';
import { put_log } from 'base/ctl/log';
import { ck_test_val, ck_tech, ck_zero, ck_std, ck_w_range, ck_dia_range } from './check';

const do_ready = (step, umd, watch) => {
    let [w, d] = ck_test_val(step);
    if (!w) {
        watch.startWatch();
        return;
    }

    const psn = get_gun(step);
    if (!psn) {
        umd.mset({
            out_w_real: w,
            out_dia_real: d,
        });

        watch.startWatch();
        return;
    }

    const anum = g_db.anum() + 1;
    const dnum = g_db.dnum();
    let snum = g_db.snum() + 1;

    if (snum > dnum) {
        snum = 1;
    }

    g_db.s_snum(snum);
    g_db.s_anum(anum);

    umd.mset({
        psn: psn,
        snum: snum,
        anum: anum,
    });

    s_psn(psn);
    set_st(umd, "test");

    clear_gun(watch);
};

const do_test = (step, umd, watch) => {
    const herr = (e, ng=false) => {
        umd.set("err", e);

        if (ng) {
            const ng = g_db.ng() + 1;

            g_db.s_ng(ng);
            umd.set("ng", ng);
        }

        watch.startWatch();
    };

    const [te, out_w_tech, out_dia_tech] = ck_tech();
    if (te) {
        return herr(te);
    }

    const [ze, out_w_zero, out_dia_zero] = ck_zero();
    if (ze) {
        return herr(ze);
    }

    const [se, out_w_std, out_dia_std] = ck_std();
    if (se) {
        return herr(se);
    }

    const [ue, out_w_up, out_w_down] = ck_w_range();
    if (ue) {
        return herr(ue);
    }

    const [de, out_dia_up, out_dia_down] = ck_dia_range();
    if (de) {
        return herr(de);
    }

    let [w, d] = ck_test_val(step);
    if (!w) {
        watch.startWatch();
        return;
    }

    let [width, dia] = ck_test_val(step, "f");
    if (!width) {
        umd.mset({
            out_w_real: w,
            out_dia_real: d,
            out_w_calc: w - out_w_std + out_w_zero,
            out_dia_calc: d - out_dia_std + out_dia_zero,
        });

        watch.startWatch();

        return;
    }

    const w_real = width - out_w_std + out_w_zero;
    const d_real = dia - out_dia_std + out_dia_zero;

    const w_val = w_real - out_w_tech;
    const d_val = d_real - out_dia_tech;

    const val = {
        out_w_real: width,
        out_dia_real: dia,
        out_w_calc: w_real,
        out_dia_calc: d_real,
        out_w_val: w_val,
        out_dia_val: d_val,
    };

    const tsn = g_db.tech();
    if (!tsn) {
        return herr("请设置型号");
    }

    const psn = g_psn();
    if (!psn) {
        return herr("请扫描单圈二维码");
    }

    umd.mset(val);

    const w_zero = out_w_zero - out_w_tech;
    const d_zero = out_dia_zero - out_dia_tech;

    const w_r = w_val - w_zero;
    const d_r = d_val - d_zero;

    put_log("检查宽度", `${w_val} - ${w_zero} = ${w_r}`, `[${out_w_down}, ${out_w_up}]`);

    if (w_r < out_w_down || w_r > out_w_up) {
        return herr("宽度不合格", true);
    }

    put_log("检查圆度", `${d_val} - ${d_zero} = ${d_r}`, `[${out_dia_down}, ${out_dia_up}]`);

    if (d_r < out_dia_down || d_r > out_dia_up) {
        return herr("圆度不合格", true);
    }

    const wsn = g_wsn();

    urlTb(null, "chunk",
        {
            tab: "real",
            line: cline(),
            data: [{
                psn: psn,
                wsn: wsn,
                k: {
                    tsn: tsn,
                },
                v: {
                    width: w_real,
                    dia: d_real,
                }
            }]
        }, r => {
            send_step(null, { fwidth: "", fdia: "" });

            const ok = g_db.ok() + 1;
            g_db.s_ok(ok);

            umd.mset({
                err: "",
                psn: "",
                ok: ok,
            });

            s_psn("");
            set_st(umd, "ready");

            watch.startWatch();
        }, () => herr("保存数据错误"));
};

const do_std = (step, umd, watch) => {
    let [w, d] = ck_test_val(step);
    if (!w) {
        watch.startWatch();
        return;
    }

    let [width, dia] = ck_test_val(step, "f");
    if (!width) {
        umd.mset({
            out_w_std: w,
            out_dia_std: d,
        });

        watch.startWatch();

        return;
    }

    const val = {
        out_w_std: width,
        out_dia_std: dia,
    };

    uDb(null, "file/md",
        {
            p: "setting",
            sn: "opt",
            v: val,
        },
        r => {
            send_step(null, { fwidth: "", fdia: "" });

            umd.mset({
                ...val,
                err: "完成标定",
            });

            set_st(umd, "");

            watch.startWatch();
        },
        e => {
            umd.set("err", "标定错误");

            set_st(umd, "");
            watch.startWatch();
        }
    );
};

export {do_std, do_test, do_ready};
